package com.zk.interceptor;

import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;

import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.saaj.SAAJInInterceptor;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * WebService服务请求拦截器
 * 验证请求消息的请求头参数是否完整，若缺少必填项则直接返回失败
 * @author xiaoxiong
 *
 */
public class RequestInterceptor extends AbstractPhaseInterceptor<SoapMessage>{

	private Logger logger = LoggerFactory.getLogger(RequestInterceptor.class);
	
	private SAAJInInterceptor saa = new SAAJInInterceptor();
	
	/**
	 * 默认构造函数
	 * 在拦截器构造完毕后，将SAAJInInterceptor注入
	 */
	public RequestInterceptor() {
		super(Phase.PRE_PROTOCOL);
		getAfter().add(SAAJInInterceptor.class.getName());
	}

	/**
	 * 接口处理消息方法实现
	 * 1、验证请求用户权限，若不通过则抛出异常消息“权限验证不通过!”
	 * 2、请求消息内容检测，若不通过则抛出异常消息“消息内容不完整!”
	 */
	public void handleMessage(SoapMessage message) throws Fault {
		logger.debug(message.getId() + ":" + message.getDestination().getAddress());
		SOAPMessage soapMsg = message.getContent(SOAPMessage.class);
		if(soapMsg == null) {
			saa.handleMessage(message);
			soapMsg = message.getContent(SOAPMessage.class);
		}
		if(!messageAuthenticate(soapMsg)) {
			throw new Fault(new Exception("权限验证不通过!"));
		}
		if(!messageValid(soapMsg)) {
			throw new Fault(new Exception("消息内容不完整!"));
		}
	}

	/**
	 * 请求消息鉴权，不通过则返回false
	 * @param soapMsg	服务请求消息
	 * @return true/false
	 */
	private boolean messageAuthenticate(SOAPMessage soapMsg) {
		SOAPHeader header = null;
        try {
            header = soapMsg.getSOAPHeader();
            NodeList userNodes = header.getElementsByTagName("username");
            NodeList passNodes = header.getElementsByTagName("password");
            if(userNodes.getLength() != 0 && passNodes.getLength() != 0){
                Node userNode = userNodes.item(0);
                Node passNode = passNodes.item(0);
                String username = userNode.getNodeValue();
                String password = passNode.getNodeValue();
                logger.debug("用户名:" + username + ", 密码:" + password);
                return true;
            }
        } catch (SOAPException e) {
            e.printStackTrace();
            return false;
        }
        return true;
	}
	
	/**
	 * 请求消息内容检测
	 * @param soapMsg	服务请求消息
	 * @return true/false
	 */
	private boolean messageValid(SOAPMessage soapMsg) {
		
		return true;
	}
}
